#include "LinkParser.h"
#include "CanonicalConv.h"
#include "Statistics.h"
#include <pthread.h>
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
//#define STATS

using namespace std;

LinkParser::LinkParser()
{
}

LinkParser::~LinkParser()
{
}

int LinkParser::getLinksFromFile(NCManager* ship,ifstream* htmlBase, const string baseUrl)
{
	time_t start;
#ifdef STATS
	start = time(&start);
#endif
	string line;
	int amount =0;
	  if (htmlBase->is_open())
	  {
		  while (! htmlBase->eof() )
	    {
	      getline (*htmlBase,line);
	   //   cout << "LINE IS: " << line << endl;
	      
	      int scriptPos = line.find("<script");
	      if (scriptPos != string::npos)
	      {
	    	  do
	    	  {
	    		  getline (*htmlBase,line);
	    	//	  cout << "SCRIPT LINE IS: " << line << endl;
	    		  scriptPos = line.find("</script>");
	    	  }
	    	  while ((scriptPos == string::npos)&&(! htmlBase->eof()));
	    //	  cout << "Saiu do Script: ";
	      }
	      
	      
	      int lastPos = line.find("href");
	      while(lastPos != string::npos)
	      {
	    	  int java = line.find("javascript",lastPos);
	    	  if(java != string::npos)
	    		  break;
	    	  int first = line.find("\"",lastPos);
	    	  int vazio = line.find(" ",lastPos);
	    	//  cout << "FIRST is: " << first <<endl;
	    	  if (first == string::npos || vazio < first)
	    		  break;
	    	  else
	    	  {
	    		  int second = line.find("\"",first+1);
	    		  vazio = line.find(" ",first+1);
	    		 // cout << "SECOND is: " << second <<endl;
	    		  if(second == string::npos || vazio < second)
	    			  break;
	    		  else
	    		  {
	    			  if((second-first-1)>400)
	    				  break;
	    			  string sub = line.substr(first+1,second-first-1);
	    		//	  cout << "%%%%%%%%%URL RAW: " << sub << endl; 
	    			  string str="";
	    			  if(LinkParser::PossuiExtensaoProibida(sub))
	    				  break;
	    			  if( (first + 1) < line.length() && second < line.length())
	    				  str = LinkParser::tratarLinks(line.substr(first+1,second - first-1 ),baseUrl);
	    			  else
	    				  break;
	    			  //cout << "%%%%%%%%URL TREATED: " << str << endl; 
	    			  pthread_mutex_lock(&ship->queueMutex);
	    			  if(str.size() < 300 && CanonicalConv::getCanonicalDomain(str).size() < 40)
				  	ship->addToVisitQueue(str);
	    			  pthread_mutex_unlock(&ship->queueMutex);
	    			  amount++;
	    		  }
	    	  }
	    	  lastPos = line.find("href", lastPos+5);
	      }
	      
	      
	      
	    }
	    htmlBase->close();
	  }
	//  printvector(&linkvector);
#ifdef STATS
	time_t end = time(&end);
	pthread_mutex_lock(&Statistics::LP_Mutex);
	Statistics::LP_calls++;
	Statistics::LP_time += (end-start);
	pthread_mutex_unlock(&Statistics::LP_Mutex);
#endif
	return amount;
}

bool LinkParser::PossuiExtensaoProibida(string url)
{
	size_t pos;
	size_t fim = url.length()-5;
	/*pos = url.find(".css",fim);
	if(pos!= string::npos)
		return true;*/	
	pos = url.find(".ico",fim);
	if(pos!= string::npos)
		return true;
	pos = url.find(".jpg",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".gif",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".jpeg",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".png",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".pdf",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".doc",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".mp3",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".wav",fim);
		if(pos!= string::npos)
			return true;	
	pos = url.find(".mov",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".tif",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".xml",fim);
		if(pos!= string::npos)
			return true;	
	pos = url.find(".css",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find(".ppt",fim);
		if(pos!= string::npos)
			return true;
	pos = url.find("mailto:",fim);
		if(pos!= string::npos)
			return true;
	return false;
}

int LinkParser::getLinksFromFile(NCManager* ship,string htmlbase, const string baseUrl)
{
	time_t start;
#ifdef STATS
	start = time(&start);
#endif
	std::ifstream file;
	string modUrl = htmlbase.substr(0,3).append("/").append(htmlbase);
	file.open(modUrl.c_str(),ifstream::in);

	if(file.is_open())
	{
	//	cout << "Could open file" <<endl;
		int resp = getLinksFromFile(ship, &file,baseUrl);
		if(file.is_open())
			file.close();
#ifdef STATS
	time_t end = time(&end);
	pthread_mutex_lock(&Statistics::LP_Mutex);
	Statistics::LP_calls++;
	Statistics::LP_time += (end-start);
	pthread_mutex_unlock(&Statistics::LP_Mutex);
#endif
		return resp;
	}
	else
	{
	//	cout << " Couldn't open file" << endl;
#ifdef STATS
	time_t end = time(&end);
	pthread_mutex_lock(&Statistics::LP_Mutex);
	Statistics::LP_calls++;
	Statistics::LP_time += (end-start);
	pthread_mutex_unlock(&Statistics::LP_Mutex);
#endif
		return -1;
	}
	
}


string LinkParser::tratarLinks(string baseLink, string baseUrl)
{
	if(baseLink.find("http://") != 0 && baseLink.find("https://") != 0)
	{
		
		if(baseLink.find("/")!=0)
		{
			string aux = "/";
			aux.append(baseLink);
			baseLink = aux;
		}
		string s = baseUrl.substr(0).append(baseLink);
		string sConv = CanonicalConv::toCanonical(s);
	//	cout << " tratei o link relativo para --> " << sConv <<endl;
		return sConv;
	}
	else return CanonicalConv::toCanonical(baseLink);
		
		
}	
